Problem
Tower
Description
最近在玩一款很好玩的游戏,游戏规则是这样的:
有一个的地图,地图上的每一个位置要么是空地,要么是炮塔,要么是一些狗,需要操纵炮塔攻击狗们。
攻击方法是:对于每个炮塔,游戏系统已经给出它可以瞄准的方向(上下左右其中一个),需要选择它的攻击位置,每一个炮塔只能够攻击一个位置,炮塔只能够向着它的瞄准方向上的某个位置发动攻击,当然炮塔也可以不进行攻击。炮塔威力强大,它可以且仅可以消灭目标位置上所有的狗。
出于安全考虑,游戏系统已经保证不存在一个炮塔能够瞄准另外一个炮塔,即对于任意一个炮塔,它所有可能的攻击位置上不存在另外一个炮塔。而且,如果把炮塔的起点和终点称为炮弹的运行轨迹,那么系统不允许两条轨迹相交(包括起点和终点)。
现在,选定目标位置以后,每一个炮塔同时开炮,你要告诉,他最多可以干掉多少狗。
Input
第一行两个正整数,表示地图的规模。
接下来礼行,每行个整数,表示空地,分别表示瞄准上下左右的炮塔,若为正整数,则表示该位置有个狗。
Output
Sample Input
1 | 3 2 |
Sample Output
1 | 9 |
HINT
每个位置的狗数量不超过个
保证不存在任意一个炮塔能够瞄准另外一个炮塔
标签:最小割
Solution
经典最小割建模之一。
网格图可以拆成两个图,即所有行组成的图和所有列组成的图。这样原图中每个点变成两个,在行图上的称为行点,在列图上的称为列点。对于点,不妨设其行点为,列点为。
图上的向左或向右的炮将图分为若干横向的链,每个炮可以打到的区域都是一条链。在这个区域中,我们找出贡献最大的点,作为基础贡献,将此链上不所有同于的点的贡献变为。对于每条链,我们从左往右或从右往左串联,连边流量为点的新贡献,这样割掉这条边表示用这条链所对应的炮打的位置。如此,链被分为两段,从链首到为一段,从到链尾为另一段,符合割的定义。对于所有向上或向下的炮也如法炮制,只不过前者在行图上连,后者在列图上连。每个点的行点和列点间连流量为的边,代表无法割断。
重新整理一下建图:
对于点,若
- 连边流量为
- 对于其可以打到的链上的点,连边流量为,其中为此链上的最大值
- 连边流量为
- 对于其可以打到的链上的点,连边流量为,其中为此链上的最大值
- ,连边流量为
建模后跑最大流求最小割,答案为。
Code
1 |
|